﻿
#ifndef _LST_LOG_20220128_H_
#define _LST_LOG_20220128_H_
#include <sstream>
#ifdef WIN32
//#include <sys/timeb.h>
#include <time.h>
#else
#include <sys/time.h>
#endif

#include "SLT_tool_pub_def.h"

static void SLT_AscToHex2(const char* strasc, int asclen, std::string& _out)
{
	char buf[16];
	for (int i = 0; i < asclen; ++i)
	{
		if (i % 16 == 0) {
			_out += "_";
		}if (i % 2 == 0) {
			_out += " ";
		}
		snprintf(buf, sizeof(buf), "%02X", (unsigned char)strasc[i]);
		_out += buf;
	}
}
static std::string SLT_AscToHex2(const char* strasc, int asclen)
{
	std::string str;
	SLT_AscToHex2(strasc, asclen, str);
	return str;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum SLT_LOG_LEVEL
{
	SLT_TRACE,
	SLT_DEBUG,
	SLT_INFO,
	SLT_WARM,
	SLT_ERROR,
	SLT_FATAL,
	SLT_MAX,
	SLT_UNKNOW
};

//日志配置文件，默认进程当前目录,必须在SLT_logInit之前调用
SLT_API void	SLT_setLogConfig(const char* _configFile);
//是否打开定时扫描配置文件 默认打开 true:打开，false:关闭   
SLT_API void  SLT_enableConfig(bool _bconfig);
//设置日志输出目录，默认进程当前目录log下,,必须在SLT_logInit之前调用
SLT_API void    SLT_setLogPath(const char* _logpath);		 
//设置日志打印级别 _id：对应模块 _level：等级 [0:TRACE,1:DEBUG,2:INFO,3:WARM,4:ERROR,5:FATAL,6:MAX]
SLT_API void    SLT_setLogLevel(int _id,int _level);
//设置日志是否输出屏幕 _id：对应模块 _disp：0：不打印输出 1：异步打印输出
SLT_API void    SLT_setLogDisplay(int _id, int _disp);
//设置日志是否输出屏幕 _id：对应模块 _sync：0：不同步打印输出 1：同步打印输出
SLT_API void    SLT_setLogDisplaySync(int _id, int _sync);
//进程只调用一次。创建日志输出目录，默认进程当前目录log下		
SLT_API int		SLT_logInit();		 

SLT_API void	SLT_WriteLog(int _id,int _level, const char *_pfile,int _fileline,const char* _mesg, ...);  //输出日志
SLT_API bool	SLT_checkLogShow(int _id, int _level);  //检查日志级别是否显示


#if 0
#ifdef WIN32
#define SLT_LOG(_id,_level,_format,...) \
	if(SLT_checkLogShow(_id,_level)) {SLT_WriteLog(_id,_level,__FILE__,__LINE__,_format "\n",##__VA_ARGS__);}
#else
#define SLT_LOG(_id,_level,_format,...) \
	if(SLT_checkLogShow(_id,_level)) {SLT_WriteLog(_id,_level,__FILE__,__LINE__,_format "\n",##__VA_ARGS__);}
#endif
#endif

#define SLT_LOG(_id,_level,_format,...) \
	if (SLT_checkLogShow(_id, _level)) { SLT_WriteLog(_id, _level, __FILE__, __LINE__, _format "\n", ##__VA_ARGS__); }

#define  SLT_LOG_TRACE(_format,...) SLT_LOG(0,SLT_TRACE,_format, ##__VA_ARGS__)
#define  SLT_LOG_DEBUG(_format,...) SLT_LOG(0,SLT_DEBUG,_format, ##__VA_ARGS__)
#define  SLT_LOG_INFO(_format,...) SLT_LOG(0,SLT_INFO,_format, ##__VA_ARGS__)
#define  SLT_LOG_WARM(_format,...) SLT_LOG(0,SLT_WARM,_format, ##__VA_ARGS__)
#define  SLT_LOG_ERR(_format,...) SLT_LOG(0,SLT_ERROR,_format, ##__VA_ARGS__)


class SLT_logwriter 
{
public:
	SLT_logwriter(int _mid,int _level,const char *_pfile,int _fileline) 
	{
		m_mid = _mid; m_level = _level; m_pfile = (char*)_pfile; m_fileline = _fileline;
	}
	~SLT_logwriter() {
		//
		SLT_WriteLog(m_mid, m_level, m_pfile, m_fileline,"%s\n", m_stream.str().c_str());
	}

	template <typename T>
	inline SLT_logwriter& operator<<(const T& _log) {
		m_stream << _log;
		return *this;
	}

	std::stringstream  m_stream;
	int m_mid;
	int m_level;
	char* m_pfile;
	int m_fileline;
};

#define  SLT_LOGS_DEBUG() SLT_logwriter(0,SLT_DEBUG,__FILE__,__LINE__)
//#define  LOG(_level) SLT_logwriter(0,_level,__FILE__,__LINE__)
#endif // !_PUBLICFUNC_H_

